'''
Created on 03/03/2009

@author: eh01
'''
from daohelper import DAOHelper
from google.appengine.api import memcache
from domain.message import Message
import logging
import time

class MessageDAO(DAOHelper):
    
    message_prefix = "message_"

    def findById(self, id):
        message = Message.get_by_id(int(id))
        return message
    
    def findByNodeId(self, nodeId):
        logging.info("findByNodeId called with node id = " + nodeId)
        # check memcache first then the datastore
        messages = memcache.get(self.message_prefix + nodeId)
        if messages:
            logging.info("messages for node id = " + nodeId + " found in memcache")
            return messages
        else:
            logging.info("looking in datastore for messages for node id = " + nodeId)
            messagesQuery = Message.gql("WHERE nodeId = " + nodeId)
            messages = self.copyQueryResultsToList(messagesQuery)
            if messages:
                # add messages to memcache
                memcache.add(self.message_prefix + nodeId, messages)
        return messages
    
    def findByNodeIdMemcacheOnlyRepeatedly(self, nodeId):
        """ checks memcache each second until a result is returned """
        logging.info("findByNodeIdMemcacheOnly called with node id = " + nodeId)
        numOfChecks = 0
        # keep checking memcache until it doesn't return None
        while memcache.get(self.message_prefix + nodeId) is None:
            time.sleep(0.1)
            numOfChecks += 1
            logging.info("Number of checks = " + str(numOfChecks))
        return memcache.get(self.message_prefix + nodeId)
    
    def save(self, message):
        # before saving message, call validate on it
        message.validate()
        nodeId = message.nodeId
        messageId = -1
        if message.is_saved():
            messageId = message.key().id()
        nodeIdStr = str(nodeId)
        logging.info("saving message with node id = " + nodeIdStr + " and message id = " + str(messageId))
        message.put()
        # add message to memcache 
        messages = memcache.get(self.message_prefix + nodeIdStr)
        if messages:
            logging.info("memcache has entry for node id = " + nodeIdStr + " and new message will be added to list")
            updatedMessages = messages[:]
            updatedMessages.append(message)
            # this will override the existing entry with the updated messages for that node
            memcache.set(self.message_prefix + nodeIdStr, updatedMessages)
        else:
            logging.info("memcahce does not have an entry for node id = " + nodeIdStr + ". Entry will be added to memcache")
            memcache.set(self.message_prefix + nodeIdStr, [message])  
    
    def remove(self, messageToRemove):
        nodeId = messageToRemove.nodeId
        nodeIdStr = str(nodeId)
        messageId = messageToRemove.key().id()
        logging.info("removing message with node id = " + nodeIdStr + " and message id = " + str(messageId))
        # first remove message from memcache
        messages = memcache.get(self.message_prefix + nodeIdStr)
        if messages:
            logging.info("memcache has entry for node id = " + nodeIdStr)
            message_to_remove = None
            for message in messages:
                if message.key().id() == messageId:
                    logging.info("message exists in memcache and will be removed")
                    message_to_remove = message
                    break
            if message_to_remove:
                # if there is a message to remove, then remove it
                messages.remove(message_to_remove)
                if messages:
                    # if there are still messages for this node, then set the updated list into memcache
                    memcache.set(self.message_prefix + nodeIdStr, messages)
                else:
                    logging.info('remove node ' + nodeIdStr + ' from memcache')
                    # if there are no more messages for node, then remove node entry from memcache
                    memcache.delete(self.message_prefix + nodeIdStr)                    
                    
            
        messageToRemove.delete();